#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
@Author: kindey
@Date: 2025/8/20
@Description: 
"""
import logging
import pandas as pd
from sklearn.model_selection import train_test_split
import catboost as cb
import shap

from apps.services.dev_data_service import DevDataService as DevDS

class CatBoostService:
    logger = logging.getLogger(__name__)

    def __init__(self):
        pass

    @staticmethod
    def train_model():
        """
        CatBoost模型训练

        :return:
        """
        data_type = "rec"
        d = DevDS()
        columns = ['data_time', 'data_value']
        data = None
        start_time = '2024-11-06 00:00:00'
        end_time = '2024-12-30 23:59:59'
        dev_id = 70
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'ja_li'}, inplace=True)
        data = df

        dev_id = 64
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'shui_wei'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 479
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'liu_liang'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 267
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'xing_cheng'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 399
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'shen_suo_liang'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 328
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'jia_hao'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 329
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'su_du'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 461
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'fen_chen'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 466
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'co'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 485
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'wen_du'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 484
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'ch4'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 491
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'o2'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 493
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'feng_su'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        dev_id = 494
        dev_data_list = d.get_dev_data_by_condition(data_type, dev_id, start_time, end_time)
        df = pd.DataFrame(dev_data_list, columns=columns)
        df.rename(columns={'data_value': 'co2'}, inplace=True)
        data = pd.merge(data, df, on='data_time', how='outer')

        # 创建目标变量：基于特征的逻辑创建故障标签
        data['failure'] = ((data['ja_li'] > 30)).astype(int)
        # 准备训练数据
        X = data.drop(['failure', 'data_time'], axis=1)
        y = data['failure']

        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

        # 使用CatBoost训练模型
        model = cb.CatBoostClassifier(
            iterations=500,
            depth=6,
            learning_rate=0.1,
            loss_function='Logloss',
            verbose=False,
            random_seed=42
        )

        model.fit(X_train, y_train, eval_set=(X_test, y_test))

        # model.save_model(model_name)

        # 2. 使用SHAP解释模型
        explainer = shap.TreeExplainer(model)
        shap_values = explainer.shap_values(X_test.iloc[:])

        # 可视化SHAP值（在实际环境中可以使用shap.summary_plot等）
        threshold = 0.8
        print("SHAP值")
        for idx, shap_value in enumerate(shap_values[:]):
            for idy, value in enumerate(shap_value):
                label = ''
                if idy == 0:
                    label = 'ja_li'
                elif idy == 1:
                    label = 'shui_wei'
                elif idy == 2:
                    label = 'liu_liang'
                elif idy == 3:
                    label = 'xing_cheng'
                elif idy == 4:
                    label = 'shen_suo_liang'
                elif idy == 5:
                    label = 'jia_hao'
                elif idy == 6:
                    label = 'su_du'
                elif idy == 7:
                    label = 'fen_chen'
                elif idy == 8:
                    label = 'co'
                elif idy == 9:
                    label = 'wen_du'
                elif idy == 10:
                    label = 'ch4'
                elif idy == 11:
                    label = 'o2'
                elif idy == 12:
                    label = 'feng_su'
                elif idy == 13:
                    label = 'co2'

                if abs(value) > threshold and idy != 0:
                    print(f"第{idx}条记录")
                    print(f"{label}特征有有效影响: {value}")



        # # 3. 叶子节点编码
        # leaf_indexes = model.calc_leaf_indexes(X_test)
        # print(f"\n叶子节点索引示例（前5个样本）:")
        # print(leaf_indexes[:5])
        #
        # # 4. 使用叶子节点作为新特征
        # # 可以将这些叶子节点索引作为新特征用于其他模型
        # leaf_features = pd.DataFrame(leaf_indexes,
        #                              columns=[f'tree_{i}_leaf' for i in range(leaf_indexes.shape[1])])
        #
        # print(f"\n叶子节点特征示例:")
        # print(leaf_features.head())

    def explain_model(self,model_name):
        """
        CatBoost模型解释

        :return:
        """
        model = cb.CatBoostClassifier()
        model.load_model(model_name)

    def predict_model(self):
        """
        CatBoost模型预测

        :return:
        """

    def estimate_model(self):
        """
        CatBoost模型评估

        :return:
        """